﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AudiPyme.DAL;

namespace AudiPyme.BLL
{
    public class EmpresaInformeNegocio
    {
        //Metodo para el Informe A/R. Se genera toda la información de una empresa y se formatea para mostrarlos en el informe
        public static List<DatosEmpresaInforme> DatosEmpresa(int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<EmpresaInforme> DatEmp = from e in agenteBD.EmpresaInformeEstablecer
                                                where e.IdInforme == IdInforme && e.IdInforme != null
                                                select e;
            List<DatosEmpresaInforme> LDatosEmpr = new List<DatosEmpresaInforme>();
            DatosEmpresaInforme DatosEmpr = new DatosEmpresaInforme();
            String NombreEmpresa = (from EmpInf in agenteBD.EmpresaInformeEstablecer
                                    join Emp in agenteBD.EmpresasEstablecer on EmpInf.IdEmpresa equals Emp.IdEmpresa
                                    where EmpInf.IdInforme == IdInforme
                                    select Emp.Nombre).Single();

            foreach (EmpresaInforme Emp in DatEmp)
            {
                DatosEmpr.Nombre = NombreEmpresa;
                DatosEmpr.NumEmpleados = Emp.NumEmpleadosInf;
                DatosEmpr.Facturacion = Emp.FacturacionInf;
                DatosEmpr.IdNivelMadurezActual = Emp.MadurezActualInf;
                DatosEmpr.IdNivelMadurezDeseada = Emp.MadurezDeseadaInf;
                DatosEmpr.PSector = Emp.PesoSectorInf;
                DatosEmpr.PNegocio = Emp.PesoNegocioInf;
                DatosEmpr.PTIC = Emp.PesoTICInf;
            }
            String NSector = EmpresaInformeFactory.SectorEmpresaInforme(IdInforme);
            DatosEmpr.NSector = NSector;
            int ActivosEmp = ActivosInformeFactory.NumeroTotalesActivosEmpresaInforme(IdInforme);
            String TipoEmpresa = EmpresaInformeFactory.TipoEmpresaEmpresaInforme(IdInforme);
            DatosEmpr.NumActivos = ActivosEmp;
            DatosEmpr.NNivelMadurezActual = EmpresaInformeFactory.NMadurezActualInforme(IdInforme);
            DatosEmpr.NNivelMadurezDeseada = EmpresaInformeFactory.NMadurezDeseadaInforme(IdInforme);
            DatosEmpr.TipoEmpresa = TipoEmpresaFactory.NTipoEmpresaInforme(IdInforme);
            int NumRelTipActAmenCritEmpInf = InstanciaTipactAmenCritriesgInformeFactory.NumRelacTipAmenCritInforme(IdInforme);
            DatosEmpr.NRelTipActAmenaza = NumRelTipActAmenCritEmpInf;
            int NumRelTipActVulnInforme = InstanciaTipactVulnInformeFactory.NumRelacTipActVulnInforme(IdInforme);
            DatosEmpr.NRelTipActVulnerab = NumRelTipActVulnInforme;
            int NumRelTotEmpresa = NumRelTipActAmenCritEmpInf + NumRelTipActVulnInforme;
            DatosEmpr.NRelaciones = NumRelTotEmpresa;
            LDatosEmpr.Add(DatosEmpr);
            return LDatosEmpr;
        }

        //Método que recoge los Datos de la Empresa y los formatea para mostrarlos en un diagrama de barras 
        public static List<PuntoIntXY> DatosEmpresaInformeXY(int IdInforme)
        {
            List<PuntoIntXY> LPuntos = new List<PuntoIntXY>();
            List<String> AtributosEmpresa = new List<String>();
            AtributosEmpresa.Add("Activos");
            AtributosEmpresa.Add("Relaciones");
            AtributosEmpresa.Add("Tipo Activo - Amenaza");
            AtributosEmpresa.Add("Tipo Activo - Vulnerabilidad");
            List<int> ValoresAtributosEmp = new List<int>();
            int NumActivosEmp = ActivosInformeFactory.NumeroTotalesActivosEmpresaInforme(IdInforme);

            int NumRelTipActAmenCritEmp = InstanciaTipactAmenCritriesgInformeFactory.NumRelacTipAmenCritInforme(IdInforme);
            int NumRelTipActVuln = InstanciaTipactVulnInformeFactory.NumRelacTipActVulnInforme(IdInforme);
            int NumRelTotEmpresa = NumRelTipActAmenCritEmp + NumRelTipActVuln;
            ValoresAtributosEmp.Add(NumActivosEmp);
            ValoresAtributosEmp.Add(NumRelTotEmpresa);
            ValoresAtributosEmp.Add(NumRelTipActAmenCritEmp);
            ValoresAtributosEmp.Add(NumRelTipActVuln);

            for (int i = 0; i < ValoresAtributosEmp.Count(); i++)
            {
                PuntoIntXY nuevoPunto = new PuntoIntXY(AtributosEmpresa[i], ValoresAtributosEmp[i], "Datos Empresa");
                LPuntos.Add(nuevoPunto);
            }
            return LPuntos;
        }

        //Método que devuelve formateados en datos de diagrama de kiviat las variables de Nivel de Madurez Deseable de
        //un informe asociado a una empresa
        public static List<PuntoDoubleXY> MadurezDeseableEmpresaInformeXY(int IdInforme)
        {
            List<PuntoDoubleXY> LPuntos = new List<PuntoDoubleXY>();
            List<String> LValoresX = new List<String>();
            LValoresX.Add("Madurez Deseable");
            LValoresX.Add("Sector");
            LValoresX.Add("Facturacion");
            LValoresX.Add("TIC");
            LValoresX.Add("Media");
            List<double> LValoresEmpY = new List<double>();
            List<double> LValoresTipSecY = new List<double>();
            //Recogemos la Empresa del Informe
            EmpresaInforme EmpresaInf = EmpresaInformeFactory.EmpresaDeInforme(IdInforme);
            double MadDeseableEmp = EmpresaInf.MadurezDeseadaInf;
            double PesoSectorEmp = EmpresaInf.PesoSectorInf;
            double PesoNegocioEmp = EmpresaInf.PesoNegocioInf;
            double PesoTICEmp = EmpresaInf.PesoTICInf;
            double MediaEmp = Math.Round((double)EmpresasFactory.MediaPesos(PesoSectorEmp, PesoNegocioEmp, PesoTICEmp), 3);
            LValoresEmpY.Add(MadDeseableEmp);
            LValoresEmpY.Add(PesoSectorEmp);
            LValoresEmpY.Add(PesoNegocioEmp);
            LValoresEmpY.Add(PesoTICEmp);
            LValoresEmpY.Add(MediaEmp);
            //Valores del Informe de la Empresa
            for (int i = 0; i < LValoresX.Count(); i++)
            {
                PuntoDoubleXY nuevoPunto = new PuntoDoubleXY(LValoresX[i], LValoresEmpY[i], "Empresa");
                LPuntos.Add(nuevoPunto);
            }
            //Valores de las Empresas que sea del mismo Tipo de Empresa y Sector que la Empresa Escogida
            int IdSector = EmpresaInformeFactory.IdSectorEmpresaInforme(IdInforme);
            int IdTipoEmpresa = EmpresaInformeFactory.IdTipoEmpresaInforme(IdInforme);
            double MadDesTipoSector = Math.Round((double)EmpresasFactory.MediaMadurezDeseadaTipoSector(IdSector, IdTipoEmpresa), 3);
            double MediaPesoSector = Math.Round((double)EmpresasFactory.MediaPesoSectorTipoSector(IdSector, IdTipoEmpresa), 3);
            double MediaPesoNegocio = Math.Round((double)EmpresasFactory.MediaPesoNegocioTipoSector(IdSector, IdTipoEmpresa), 3);
            double MediaPesoTIC = Math.Round((double)EmpresasFactory.MediaPesoTICTipoSector(IdSector, IdTipoEmpresa), 3);
            double MediaSectorTipo = Math.Round((double)EmpresasFactory.MediaPesos(MediaPesoSector, MediaPesoNegocio, MediaPesoTIC), 3);
            LValoresTipSecY.Add(MadDesTipoSector);
            LValoresTipSecY.Add(MediaPesoSector);
            LValoresTipSecY.Add(MediaPesoNegocio);
            LValoresTipSecY.Add(MediaPesoTIC);
            LValoresTipSecY.Add(MediaSectorTipo);
            for (int i = 0; i < LValoresX.Count(); i++)
            {
                PuntoDoubleXY nuevoPunto = new PuntoDoubleXY(LValoresX[i], LValoresTipSecY[i], "Tipo Empresa-Sector");
                LPuntos.Add(nuevoPunto);
            }
            return LPuntos;
        }

        //Método que devuelve la fecha de un informe
        public static List<FechasInforme> FechaInforme(int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<FechasInforme> LFechas = new List<FechasInforme>();
            IQueryable<DateTime> FechInf = from Inf in agenteBD.InformesEstablecer
                                           where Inf.IdInforme == IdInforme
                                           select Inf.Fecha;
            if (FechInf.Count() == 0)
            {
                FechasInforme centinela = new FechasInforme();
                LFechas.Add(centinela);
            }
            else
            {
                DateTime fechaInforme = FechInf.First();
                String SFechaActual = fechaInforme.Day + " - " + fechaInforme.Month + " - " + fechaInforme.Year;
                FechasInforme NuevaFecha = new FechasInforme();
                NuevaFecha.FechaActual = SFechaActual;
                LFechas.Add(NuevaFecha);
            }
            return LFechas;
        }

        //Recoge el número de relaciones de un informe asociado a una empresa por tipo de activo 
        //cuyas series son Amenazas y Vulnerabilidades que se corresponden con TiposActivo-Amenazas y TiposActivo-Vulnerabilidades
        public static List<PuntoIntXY> RelacionesInforme1de2XY(int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<PuntoIntXY> LRelaciones = new List<PuntoIntXY>();
            //Recoge los Id del primer grupo de Id de Control
            List<int> LIdTiposActivo = TiposActivosFactory.RecogeIdTipoActivo1de2();
            foreach (int IdTipoActivo in LIdTiposActivo)
            {
                //Relaciones Tipo Activo-Amenaza
                int NTipActivoAmenEmp = InstanciaTipactAmenCritriesgInformeFactory.NumRelacTipAmenCritInformePorTipoActivo(IdInforme, IdTipoActivo);
                //Relaciones Tipo Activo-Vulnerabilidad
                int NTipoActivoVulnEmp = InstanciaTipactVulnInformeFactory.NumRelacTipActVulnInformePorTipoActivo(IdInforme, IdTipoActivo);
                //Si el número de relaciones con ese Tipo de Activo es mayor que 0 lo añadimos en el gráfico. Si no, no
                if (NTipActivoAmenEmp != 0 || NTipoActivoVulnEmp != 0)
                {
                    String NombreTipoActivo = TiposActivosFactory.RecogeNombreTipoActivo(IdTipoActivo);
                    PuntoIntXY PuntoTipActAmen = new PuntoIntXY();
                    PuntoTipActAmen.X = NombreTipoActivo;
                    PuntoTipActAmen.Y = NTipActivoAmenEmp;
                    PuntoTipActAmen.Serie = "Relaciones Tipo Activo - Amenazas";
                    LRelaciones.Add(PuntoTipActAmen);
                    PuntoIntXY PuntoTipActVuln = new PuntoIntXY();
                    PuntoTipActVuln.X = NombreTipoActivo;
                    PuntoTipActVuln.Y = NTipoActivoVulnEmp;
                    PuntoTipActVuln.Serie = "Relaciones Tipo Activo - Vulnerabilidad";
                    LRelaciones.Add(PuntoTipActVuln);
                }
            }
            return LRelaciones;
        }

        //Recoge el número de relaciones de un informe asociado a una empresa por tipo de activo 
        //cuyas series son Amenazas y Vulnerabilidades que se corresponden con TiposActivo-Amenazas y TiposActivo-Vulnerabilidades (según grupo de Tipos de activos)
        public static List<PuntoIntXY> RelacionesInforme2de2XY(int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<PuntoIntXY> LRelaciones = new List<PuntoIntXY>();
            //Recoge los Id del primer grupo de Id de Control
            List<int> LIdTiposActivo = TiposActivosFactory.RecogeIdTipoActivo2de2();
            foreach (int IdTipoActivo in LIdTiposActivo)
            {
                //Relaciones Tipo Activo-Amenaza
                int NTipActivoAmenEmp = InstanciaTipactAmenCritriesgInformeFactory.NumRelacTipAmenCritInformePorTipoActivo(IdInforme, IdTipoActivo);
                //Relaciones Tipo Activo-Vulnerabilidad
                int NTipoActivoVulnEmp = InstanciaTipactVulnInformeFactory.NumRelacTipActVulnInformePorTipoActivo(IdInforme, IdTipoActivo);
                //Si el número de relaciones con ese Tipo de Activo es mayor que 0 lo añadimos en el gráfico. Si no, no
                if (NTipActivoAmenEmp != 0 || NTipoActivoVulnEmp != 0)
                {
                    String NombreTipoActivo = TiposActivosFactory.RecogeNombreTipoActivo(IdTipoActivo);
                    PuntoIntXY PuntoTipActAmen = new PuntoIntXY();
                    PuntoTipActAmen.X = NombreTipoActivo;
                    PuntoTipActAmen.Y = NTipActivoAmenEmp;
                    PuntoTipActAmen.Serie = "Relaciones Tipo Activo - Amenazas";
                    LRelaciones.Add(PuntoTipActAmen);
                    PuntoIntXY PuntoTipActVuln = new PuntoIntXY();
                    PuntoTipActVuln.X = NombreTipoActivo;
                    PuntoTipActVuln.Y = NTipoActivoVulnEmp;
                    PuntoTipActVuln.Serie = "Relaciones Tipo Activo - Vulnerabilidad";
                    LRelaciones.Add(PuntoTipActVuln);
                }
            }
            return LRelaciones;
        }

        //Recoge la evolución de los empleados de una lista de informes y los formatea para mostrarlos en una tabla
        public static List<PuntoIntXY> EmpleadosPorInformes(List<int> LInformes)
        {
            List<PuntoIntXY> LEmpleados = new List<PuntoIntXY>();
            ModeloContainer agenteBD = new ModeloContainer();
            foreach (int IdInforme in LInformes)
            {
                int NumeroEmpleados = (from EmpInf in agenteBD.EmpresaInformeEstablecer
                                       where EmpInf.IdInforme == IdInforme
                                       select EmpInf.NumEmpleadosInf).Single();
                PuntoIntXY nuevoPunto = new PuntoIntXY();
                nuevoPunto.X = IdInforme.ToString();
                nuevoPunto.Y = NumeroEmpleados;
                nuevoPunto.Serie = "Número de Empleados";
                LEmpleados.Add(nuevoPunto);
            }
            return LEmpleados;
        }

        //Recoge la evolución de la facturación de una lista de informes y los formatea para mostrarlos en una tabla
        public static List<PuntoIntXY> FacturacionPorInformes(List<int> LInformes)
        {
            List<PuntoIntXY> LFacturacion = new List<PuntoIntXY>();
            ModeloContainer agenteBD = new ModeloContainer();
            foreach (int IdInforme in LInformes)
            {
                int NumeroEmpleados = (from EmpInf in agenteBD.EmpresaInformeEstablecer
                                       where EmpInf.IdInforme == IdInforme
                                       select EmpInf.FacturacionInf).Single();
                PuntoIntXY nuevoPunto = new PuntoIntXY();
                nuevoPunto.X = IdInforme.ToString();
                nuevoPunto.Y = NumeroEmpleados;
                nuevoPunto.Serie = "Facturación";
                LFacturacion.Add(nuevoPunto);
            }
            return LFacturacion;
        }

        //Método que recoge la distribución de respuestas de controles de cada una de la lista de informes, agrupados por el valor de respuesta y nivel de madurez
        public static List<PuntoDoubleXY> NivelMadurezActualPorInformes(List<int> LInformes)
        {
            List<PuntoDoubleXY> LPuntos = new List<PuntoDoubleXY>();
            foreach (int IdInforme in LInformes)
            {
                //Recogemos los controles del informe perteneciente a la empresa, asociados al nivel de madurez de cada uno
                List<ControlesCheckList> LCtrChkListEmpresa = ControlesEmpresaNegocio.RecogeControlesCheckListInforme(IdInforme);
                if (LCtrChkListEmpresa.Count == 133)
                {
                    //Con los controles de la empresa, se agrupan segun su respuesta y nivel de madurez
                    int ControlesSI = ControlesEmpresaInformeFactory.NumeroControlesSIInforme(IdInforme);
                    PuntoDoubleXY puntoSI = new PuntoDoubleXY("Sí", ControlesSI, IdInforme.ToString());
                    LPuntos.Add(puntoSI);
                    int ControlesNO = ControlesEmpresaInformeFactory.NumeroControlesNOInforme(IdInforme);
                    PuntoDoubleXY puntosNO = new PuntoDoubleXY("No", ControlesNO, IdInforme.ToString());
                    LPuntos.Add(puntosNO);
                    int ControlesPARC = ControlesEmpresaInformeFactory.NumeroControlesPARCInforme(IdInforme);
                    PuntoDoubleXY puntosPARC = new PuntoDoubleXY("Parcialmente", ControlesPARC, IdInforme.ToString());
                    LPuntos.Add(puntosPARC);
                    int ControlesNA = ControlesEmpresaInformeFactory.NumeroControlesNAInforme(IdInforme);
                    PuntoDoubleXY puntosNA = new PuntoDoubleXY("No Aplica", ControlesNA, IdInforme.ToString());
                    LPuntos.Add(puntosNA);
                    //Tomamos el nivel de Cumplimiento de los controles de cada Informe a cada Nivel de Madurez
                    int NivelMadurezActualInforme = InformesFactory.NivelMadurezActualInforme(IdInforme);
                    PuntoDoubleXY puntoCumplimiento = new PuntoDoubleXY("Nivel Madurez Actual", NivelMadurezActualInforme, IdInforme.ToString());
                    LPuntos.Add(puntoCumplimiento);
                }
            }
            return LPuntos;
        }

        //Método que recoge la evolución de los parámetros que conforman el Nivel de Madurez Deseable segun la lista de informes seleccionados
        public static List<PuntoDoubleXY> PesosMadurezDeseablePorInformes(List<int> LInformes)
        {
            List<PuntoDoubleXY> LPuntos = new List<PuntoDoubleXY>();
            foreach (int IdInforme in LInformes)
            {
                EmpresaInforme DatosEmpresaInforme = EmpresaInformeFactory.EmpresaDeInforme(IdInforme);
                double PesoSector = DatosEmpresaInforme.PesoSectorInf;
                PuntoDoubleXY puntoPesoSec = new PuntoDoubleXY("Peso Sector", PesoSector, IdInforme.ToString());
                LPuntos.Add(puntoPesoSec);
                double PesoFact = DatosEmpresaInforme.PesoNegocioInf;
                PuntoDoubleXY puntoPesoFact = new PuntoDoubleXY("Peso Facturación", PesoFact, IdInforme.ToString());
                LPuntos.Add(puntoPesoFact);
                double PesoTIC = DatosEmpresaInforme.PesoTICInf;
                PuntoDoubleXY puntoPesoTIC = new PuntoDoubleXY("Peso TIC", PesoTIC, IdInforme.ToString());
                LPuntos.Add(puntoPesoTIC);
            }
            return LPuntos;
        }

        //Método que recoge la evolución del Nivel de Madurez Deseable segun la lista de informes seleccionados
        public static List<PuntoDoubleXY> MadurezDeseablePorInformesXY(List<int> LInformes)
        {
            List<PuntoDoubleXY> LPuntos = new List<PuntoDoubleXY>();
            foreach (int IdInforme in LInformes)
            {
                EmpresaInforme DatosEmpresaInforme = EmpresaInformeFactory.EmpresaDeInforme(IdInforme);
                double NivelMadDes = DatosEmpresaInforme.MadurezDeseadaInf;
                PuntoDoubleXY nivelMad = new PuntoDoubleXY(IdInforme.ToString(), NivelMadDes, "Nivel Madurez Deseable");
                LPuntos.Add(nivelMad);
            }
            return LPuntos;
        }

        //Método que recoge para mostrar en una tabla, el número total de relaciones que hay en cada uno de los informes seleccionados
        //así como el número total de cada uno de los tipos de relaciones
        public static List<PuntoIntXY> RelacionesPorInformesXY(List<int> LInformes)
        {
            List<PuntoIntXY> LPuntos = new List<PuntoIntXY>();
            foreach (int IdInforme in LInformes)
            {
                int NumRelTipAmenCrit = InstanciaTipactAmenCritriesgInformeFactory.NumRelacTipAmenCritInforme(IdInforme);
                PuntoIntXY PuntoRelTipAmenCrit = new PuntoIntXY(IdInforme.ToString(), NumRelTipAmenCrit, "Tipo Activo - Amenaza - Criterio de Riesgo");
                LPuntos.Add(PuntoRelTipAmenCrit);
                int NumRelTipVuln = InstanciaTipactVulnInformeFactory.NumRelacTipActVulnInforme(IdInforme);
                PuntoIntXY PuntoRelTipVuln = new PuntoIntXY(IdInforme.ToString(), NumRelTipVuln, "Tipo Activo - Vulnerabilidad");
                LPuntos.Add(PuntoRelTipVuln);
                int NumTotalRelacionesInforme = NumRelTipAmenCrit + NumRelTipVuln;
                PuntoIntXY PuntoTotalRelaciones = new PuntoIntXY(IdInforme.ToString(), NumTotalRelacionesInforme, "Total");
                LPuntos.Add(PuntoTotalRelaciones);
            }
            return LPuntos;
        }

    }
}
